#define __QYQ_FRAME_MODBUS_SLAVE_C_
#include "qyq_frame_modbus_slave.h"

static uint16_t qyq_frame_modbus_slave_calculatecrc(uint8_t *data, uint16_t length)
{
    const uint16_t POLYNOMIAL = 0xA001;
    uint16_t crc = 0xFFFF;

    for (uint16_t i = 0; i < length; ++i) {
        crc ^= data[i];
        for (int j = 0; j < 8; ++j) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ POLYNOMIAL;
            } else {
                crc >>= 1;
            }
        }
    }

    // 将高低字节互换
    crc = (crc << 8) | (crc >> 8);

    return crc;
}

static void qyq_frame_modbus_slave_write_multiple_coils(uint8_t *coils_list, uint16_t startCoil, uint16_t numCoils, uint8_t *data)
{
    uint8_t bitPosition = 0;
    uint8_t bytePosition = 0;
    uint8_t bitOffset = 0;
    uint16_t i = 0;
    // 模拟写入线圈状态
    for (i = 0; i < numCoils; i++) {
        bitPosition = startCoil + i;
        bytePosition = bitPosition / 8;
        bitOffset = bitPosition % 8;

        if (data[i / 8] & (1 << (i % 8))) {
            coils_list[bytePosition] |= (1 << bitOffset); // 设置线圈状态
        } else {
            coils_list[bytePosition] &= ~(1 << bitOffset); // 清除线圈状态
        }
    }
}

static void qyq_frame_modbus_slave_write_multiple_registers(uint16_t *register_list, uint16_t startRegister, uint16_t numRegisters, uint8_t *data)
{
    // 模拟写入寄存器值
    uint16_t value = 0;
    for (int i = 0; i < numRegisters * 2; i += 2) {
        value = (data[i] << 8) | data[i + 1];
        register_list[startRegister + i / 2] = value;
    }
}

static int8_t qyq_frame_modbus_slave_functioncode_read_coils_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0, cnt = 0, i = 0;
    uint16_t startaddr = 0, coilsnum = 0, startposition = 0, coilscnt = 0;
    uint8_t tmp_value = 0;

    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[0] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[1] = QYQ_FRAME_MODBUS_SLAVE_READ_COILS;

    // 获取起始位置
    startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
    startaddr <<= 8;
    startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];

    // 获取数据的起始位置
    startposition = startaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;

    // 获取线圈数量
    coilsnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
    coilsnum <<= 8;
    coilsnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

    if (coilsnum % 8 == 0) {
        coilscnt = coilsnum / 8;
    } else {
        coilscnt = coilsnum / 8 + 1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2] = coilscnt;

    for (cnt = 0; cnt < coilscnt; cnt++) {
        tmp_value = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list[startposition / 8 + cnt] >> (startposition % 8);
        tmp_value |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list[startposition / 8 + cnt + 1] << (8 - startposition % 8);
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3 + cnt] = tmp_value;
    }

    if (coilsnum % 8 != 0) {
        tmp_value = 0;
        for (i = 0; i < coilsnum % 8; i++) {
            tmp_value <<= 1;
            tmp_value += 1;
        }
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2 + coilscnt] &= tmp_value;
    }

    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 3 + coilscnt);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3 + coilscnt] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[4 + coilscnt] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 5 + coilscnt);

    return 0;
}

static int8_t qyq_frame_modbus_slave_functioncode_read_discrete_inputs_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0, cnt = 0, i = 0;
    uint16_t startaddr = 0, coilsnum = 0, startposition = 0, coilscnt = 0;
    uint8_t tmp_value = 0;

    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[0] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[1] = QYQ_FRAME_MODBUS_SLAVE_READ_DISCRETE_INPUTS;

    // 获取起始位置
    startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
    startaddr <<= 8;
    startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];

    // 获取数据的起始位置
    startposition = startaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;

    // 获取线圈数量
    coilsnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
    coilsnum <<= 8;
    coilsnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

    if (coilsnum % 8 == 0) {
        coilscnt = coilsnum / 8;
    } else {
        coilscnt = coilsnum / 8 + 1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2] = coilscnt;

    for (cnt = 0; cnt < coilscnt; cnt++) {
        tmp_value = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list[startposition / 8 + cnt] >> (startposition % 8);
        tmp_value |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list[startposition / 8 + cnt + 1] << (8 - startposition % 8);
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3 + cnt] = tmp_value;
    }

    if (coilsnum % 8 != 0) {
        tmp_value = 0;
        for (i = 0; i < coilsnum % 8; i++) {
            tmp_value <<= 1;
            tmp_value += 1;
        }
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2 + coilscnt] &= tmp_value;
    }

    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 3 + coilscnt);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3 + coilscnt] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[4 + coilscnt] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 5 + coilscnt);

    return 0;
}

static int8_t qyq_frame_modbus_slave_functioncode_read_holding_registers_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0, cnt = 0;
    uint16_t startaddr = 0, coilsnum = 0, startposition = 0;

    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[0] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[1] = QYQ_FRAME_MODBUS_SLAVE_READ_HOLDING_REGISTERS;

    // 获取起始位置
    startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
    startaddr <<= 8;
    startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];

    // 获取数据的起始位置
    startposition = startaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;

    // 获取线圈数量
    coilsnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
    coilsnum <<= 8;
    coilsnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2] = coilsnum * 2;

    for (cnt = 0; cnt < coilsnum; cnt++) {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3 + cnt * 2] = (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list[startaddr + cnt] >> 8) & 0x00FF;
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[4 + cnt * 2] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list[startaddr + cnt] & 0x00FF;
    }

    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, coilsnum * 2 + 3);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[coilsnum * 2 + 3] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[coilsnum * 2 + 4] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, coilsnum * 2 + 5);

    return 0;
}

static int8_t qyq_frame_modbus_slave_functioncode_read_input_registers_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0, cnt = 0;
    uint16_t startaddr = 0, coilsnum = 0, startposition = 0;

    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[0] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[1] = QYQ_FRAME_MODBUS_SLAVE_READ_INPUT_REGISTERS;

    // 获取起始位置
    startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
    startaddr <<= 8;
    startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];

    // 获取数据的起始位置
    startposition = startaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;

    // 获取线圈数量
    coilsnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
    coilsnum <<= 8;
    coilsnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2] = coilsnum * 2;

    for (cnt = 0; cnt < coilsnum; cnt++) {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3 + cnt * 2] = (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list[startaddr + cnt] >> 8) & 0x00FF;
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[4 + cnt * 2] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list[startaddr + cnt] & 0x00FF;
    }

    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, coilsnum * 2 + 3);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[coilsnum * 2 + 3] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[coilsnum * 2 + 4] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, coilsnum * 2 + 5);

    return 0;
}

static int8_t qyq_frame_modbus_slave_functioncode_write_single_coil_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t cnt = 0;
    uint16_t startaddr = 0, startposition = 0;
    uint32_t read_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index;

    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    // 获取起始位置
    startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
    startaddr <<= 8;
    startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];

    // 获取数据的起始位置
    startposition = startaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;

    // 开，用1表示
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4] == 0xFF) {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list[startposition / 8] |= (1 << (startposition % 8));
    } else {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list[startposition / 8] &= ~(1 << (startposition % 8));
    }

    for (cnt = 0; cnt < read_size; cnt++) {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[cnt] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[cnt];
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, read_size);

    return 0;
}

static int8_t qyq_frame_modbus_slave_functioncode_write_single_register_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t cnt = 0;
    uint16_t startaddr = 0, startposition = 0;
    uint16_t tmp_value = 0;
    uint32_t read_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index;

    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    // 获取起始位置
    startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
    startaddr <<= 8;
    startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];

    // 获取数据的起始位置
    startposition = startaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;

    // 临时值
    tmp_value = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
    tmp_value <<= 8;
    tmp_value |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list[startposition] = tmp_value;

    for (cnt = 0; cnt < read_size; cnt++) {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[cnt] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[cnt];
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, read_size);

    return 0;
}

static int8_t qyq_frame_modbus_slave_functioncode_write_multiple_coils_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0, cnt = 0, i = 0;
    uint16_t startaddr = 0, startposition = 0, coilsnum = 0;
    uint32_t read_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index;
    uint8_t tmp_value = 0, write_size = 0;

    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    // 获取起始位置
    startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
    startaddr <<= 8;
    startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];
    // 获取数据的起始位置
    startposition = startaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;

    // 获取线圈数量
    coilsnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
    coilsnum <<= 8;
    coilsnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

    qyq_frame_modbus_slave_write_multiple_coils(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list, startposition, coilsnum, &qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[7]);

    for (cnt = 0; cnt < 6; cnt++) {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[cnt] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[cnt];
    }

    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 6);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[6] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[7] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 8);

    return 0;
}

static int8_t qyq_frame_modbus_slave_functioncode_write_multiple_registers_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0, cnt = 0, i = 0;
    uint16_t startaddr = 0, startposition = 0, registernum = 0;
    uint32_t read_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index;
    uint8_t tmp_value = 0, write_size = 0;

    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    // 获取起始位置
    startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
    startaddr <<= 8;
    startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];
    // 获取数据的起始位置
    startposition = startaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;

    // 获取寄存器数量
    registernum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
    registernum <<= 8;
    registernum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

    qyq_frame_modbus_slave_write_multiple_registers(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list, startposition, registernum, &qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[7]);

    for (cnt = 0; cnt < 6; cnt++) {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[cnt] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[cnt];
    }

    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 6);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[6] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[7] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 8);

    return 0;
}

static int8_t qyq_frame_modbus_slave_exceptioncode_server_device_failure_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0;
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[0] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[1] = 0x80 | qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1];
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2] = QYQ_FRAME_MODBUS_SLAVE_SERVER_DEVICE_FAILURE;
    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 3);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[4] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 5);

    return 0;
}

static int8_t qyq_frame_modbus_slave_exceptioncode_illegal_data_value_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0;
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[0] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[1] = 0x80 | qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1];
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2] = QYQ_FRAME_MODBUS_SLAVE_ILLEGAL_DATA_VALUE;
    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 3);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[4] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 5);
    return 0;
}

static int8_t qyq_frame_modbus_slave_exceptioncode_illegal_data_address_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0;
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[0] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[1] = 0x80 | qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1];
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2] = QYQ_FRAME_MODBUS_SLAVE_ILLEGAL_DATA_ADDRESS;
    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 3);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[4] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 5);
    return 0;
}

static int8_t qyq_frame_modbus_slave_exceptioncode_illegal_function_ack(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0;
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[0] = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[1] = 0x80 | qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1];
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[2] = QYQ_FRAME_MODBUS_SLAVE_ILLEGAL_FUNCTION;
    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 3);
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[3] = (modbus_crc >> 8) & 0x00FF;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf[4] = modbus_crc & 0x00FF;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_config_write(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf, 5);
    return 0;
}

static int8_t qyq_frame_modbus_slave_analysis(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint32_t rev_size = 0;
    uint16_t modbus_crc = 0;
    uint16_t startaddr = 0, addr_size = 0, addrnum = 0;
    uint16_t coils_status = 0;
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    // qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr
    rev_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index;
    modbus_crc = qyq_frame_modbus_slave_calculatecrc(qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf, rev_size - 2);
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[0] == qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_addr) {
        // 判断从机接收数据是否OK
        if ((qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[rev_size - 2] == ((modbus_crc >> 8) & 0x00FF)) && (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[rev_size - 1] == (modbus_crc & 0x00FF))) {
            if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1] != QYQ_FRAME_MODBUS_SLAVE_READ_COILS &&
                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1] != QYQ_FRAME_MODBUS_SLAVE_READ_DISCRETE_INPUTS &&
                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1] != QYQ_FRAME_MODBUS_SLAVE_READ_HOLDING_REGISTERS &&
                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1] != QYQ_FRAME_MODBUS_SLAVE_READ_INPUT_REGISTERS &&
                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1] != QYQ_FRAME_MODBUS_SLAVE_WRITE_SINGLE_COIL &&
                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1] != QYQ_FRAME_MODBUS_SLAVE_WRITE_SINGLE_REGISTER &&
                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1] != QYQ_FRAME_MODBUS_SLAVE_WRITE_MULTIPLE_COILS &&
                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1] != QYQ_FRAME_MODBUS_SLAVE_WRITE_MULTIPLE_REGISTERS) {
                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_FUNCTION;
            } else {
                startaddr = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[2];
                startaddr <<= 8;
                startaddr |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[3];
                switch (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[1]) {
                    case QYQ_FRAME_MODBUS_SLAVE_READ_COILS:
                        if ((startaddr < qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr) || (startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_endaddr)) {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                        } else {
                            addr_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_endaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;
                            // 获取数量
                            addrnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
                            addrnum <<= 8;
                            addrnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

                            if (addrnum > addr_size) {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                            } else {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_READ_COILS;
                            }
                        }
                        break;

                    case QYQ_FRAME_MODBUS_SLAVE_READ_DISCRETE_INPUTS:
                        if ((startaddr < qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list_startaddr) || (startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list_endaddr)) {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                        } else {
                            addr_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list_endaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list_startaddr;
                            // 获取数量
                            addrnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
                            addrnum <<= 8;
                            addrnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

                            if (addrnum > addr_size) {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                            } else {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_READ_DISCRETE_INPUTS;
                            }
                        }
                        break;
                    case QYQ_FRAME_MODBUS_SLAVE_READ_HOLDING_REGISTERS:
                        if ((startaddr < qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_startaddr) || (startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_endaddr)) {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                        } else {
                            addr_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_endaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_startaddr;
                            // 获取数量
                            addrnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
                            addrnum <<= 8;
                            addrnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

                            if (addrnum > addr_size) {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                            } else {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_READ_HOLDING_REGISTERS;
                            }
                        }
                        break;
                    case QYQ_FRAME_MODBUS_SLAVE_READ_INPUT_REGISTERS:
                        if ((startaddr < qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list_startaddr) || (startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list_endaddr)) {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                        } else {
                            addr_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list_endaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list_startaddr;
                            // 获取数量
                            addrnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
                            addrnum <<= 8;
                            addrnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

                            if (addrnum > addr_size) {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                            } else {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_READ_INPUT_REGISTERS;
                            }
                        }
                        break;
                    case QYQ_FRAME_MODBUS_SLAVE_WRITE_SINGLE_COIL:
                        if ((startaddr < qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr) || (startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_endaddr)) {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                        } else {
                            coils_status = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
                            coils_status <<= 8;
                            coils_status |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];
                            if ((coils_status != 0xFF00) && (coils_status != 0x0000)) {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_VALUE;
                            } else {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_WRITE_SINGLE_COIL;
                            }
                        }
                        break;
                    case QYQ_FRAME_MODBUS_SLAVE_WRITE_SINGLE_REGISTER:
                        if ((startaddr < qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_startaddr) || (startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_endaddr)) {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                        } else {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_WRITE_SINGLE_REGISTER;
                        }
                        break;
                    case QYQ_FRAME_MODBUS_SLAVE_WRITE_MULTIPLE_COILS:
                        if ((startaddr < qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr) || (startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_endaddr)) {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                        } else {
                            // 判断写线圈的大小是否在范围内
                            addr_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_endaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr;
                            // 获取数量
                            addrnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
                            addrnum <<= 8;
                            addrnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

                            if (addrnum > addr_size) {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                            } else {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_WRITE_MULTIPLE_COILS;
                            }
                        }
                        break;
                    case QYQ_FRAME_MODBUS_SLAVE_WRITE_MULTIPLE_REGISTERS:
                        if ((startaddr < qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_startaddr) || (startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_endaddr)) {
                            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                        } else {
                            // 判断写寄存器的大小是否在范围内
                            addr_size = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_endaddr - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_startaddr;
                            // 获取数量
                            addrnum = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[4];
                            addrnum <<= 8;
                            addrnum |= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[5];

                            if (addrnum > addr_size) {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS;
                            } else {
                                qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_WRITE_MULTIPLE_REGISTERS;
                            }
                        }
                        break;

                    default:
                        break;
                }
            }
        } else {
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_VALUE;
        }
    } else {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    }

    return 0;
}

int8_t qyq_frame_modbus_slave_init(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_writebuf == null) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf == null) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list == null) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list == null) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list == null) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list == null) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_coils_list_endaddr) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list_startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_discrete_inputs_list_endaddr) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_holding_registers_list_endaddr) {
        return -1;
    }
    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list_startaddr > qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_input_registers_list_endaddr) {
        return -1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_tick_count = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_bench_timer = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_INITIAL;

    return 0;
}

int8_t qyq_frame_modbus_slave_tick(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_tick_count++;

    return 0;
}

int8_t qyq_frame_modbus_slave_run(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave)
{
    uint16_t modbus_crc = 0;
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    switch (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states) {
        case QYQ_FRAME_MODBUS_SLAVE_INITIAL:
            /* code */
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION:
            if ((qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status == 1) && (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_tick_count - qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_bench_timer) > QYQ_FRAME_MODBUS_SLAVE_READ_END_TIME) {
                qyq_frame_modbus_slave_analysis(qyq_frame_modbus_slave);
            }
            break;

        case QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_READ_COILS:
            qyq_frame_modbus_slave_functioncode_read_coils_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_READ_DISCRETE_INPUTS:
            qyq_frame_modbus_slave_functioncode_read_discrete_inputs_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_READ_HOLDING_REGISTERS:
            qyq_frame_modbus_slave_functioncode_read_holding_registers_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_READ_INPUT_REGISTERS:
            qyq_frame_modbus_slave_functioncode_read_input_registers_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_WRITE_SINGLE_COIL:
            qyq_frame_modbus_slave_functioncode_write_single_coil_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_WRITE_SINGLE_REGISTER:
            qyq_frame_modbus_slave_functioncode_write_single_register_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_WRITE_MULTIPLE_COILS:
            qyq_frame_modbus_slave_functioncode_write_multiple_coils_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_FUNCTIONCODE_WRITE_MULTIPLE_REGISTERS:
            qyq_frame_modbus_slave_functioncode_write_multiple_registers_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_FUNCTION:
            qyq_frame_modbus_slave_exceptioncode_illegal_function_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_ADDRESS:
            qyq_frame_modbus_slave_exceptioncode_illegal_data_address_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_ILLEGAL_DATA_VALUE:
            qyq_frame_modbus_slave_exceptioncode_illegal_data_value_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        case QYQ_FRAME_MODBUS_SLAVE_EXCEPTIONCODE_SERVER_DEVICE_FAILURE:
            qyq_frame_modbus_slave_exceptioncode_server_device_failure_ack(qyq_frame_modbus_slave);
            qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_states = QYQ_FRAME_MODBUS_SLAVE_WAIT_RECEPTION;
            break;

        default:
            break;
    }

    return 0;
}

int8_t qyq_frame_modbus_slave_recv(struct qyq_frame_modbus_slave_type *qyq_frame_modbus_slave, uint8_t dat)
{
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_bench_timer = qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_tick_count - 1;

    if (qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index >= qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf_size) {
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index = 0;
        qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 0;
        // 表示数据满了，返回状态信息
        return -2;
    }
    // 更新时间和数据
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readbuf[qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_read_index++] = dat;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config->qyq_frame_modbus_slave_readready_status = 1;

    return 0;
}

int8_t qyq_frame_modbus_slave_create(qyq_frame_modbus_slave_type_t *qyq_frame_modbus_slave, qyq_frame_modbus_slave_config_t *qyq_frame_modbus_slave_config)
{
    if (qyq_frame_modbus_slave == null) {
        return -1;
    }

    if (qyq_frame_modbus_slave_config == null) {
        return -1;
    }

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_config = qyq_frame_modbus_slave_config;

    qyq_frame_modbus_slave->qyq_frame_modbus_slave_init = qyq_frame_modbus_slave_init;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_tick = qyq_frame_modbus_slave_tick;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_run = qyq_frame_modbus_slave_run;
    qyq_frame_modbus_slave->qyq_frame_modbus_slave_recv = qyq_frame_modbus_slave_recv;

    return 0;
}
